import inspect
from pprint import pprint
import json
from deeppavlov import configs
from deeppavlov.core.data.sqlite_database import Sqlite3Database
from deeppavlov.core.common.file import read_json
from deeppavlov.core.commands.train import train_evaluate_model_from_config as train_model
from deeppavlov import evaluate_model, build_model

from deeppavlov.core.datahelpers.dstc2_reader import SimpleDSTC2DatasetReader
from deeppavlov.core.datahelpers.dstc2_iterator import DialogDatasetIterator


def database():
    data = SimpleDSTC2DatasetReader().read('my_data')
    iterator = DialogDatasetIterator(data)

    # build database of items
    database = Sqlite3Database(primary_keys=['name'], save_path='./my_bot/db.sqlite')

    db_results = []
    for dialog in iterator.gen_batches(batch_size=1, data_type='all'):
        turns_x, turns_y = dialog
        db_results.extend(x['db_result'] for x in turns_x[0] if x.get('db_result'))
    print(f'Adding {len(db_results)} items.')
    if db_results:
        database.fit(db_results)

    # build solt filler
    slotfill_config = read_json(configs.ner.slotfill_simple_dstc2_raw)
    slotfill_config['metadata']['variables']['DATA_PATH'] = 'my_data'
    slotfill_config['metadata']['variables']['SLOT_VALS_PATH'] = 'my_bot/slotfill/dstc_slot_vals.json'

    evaluate_model(slotfill_config)     # evaluate
    slotfill = build_model(slotfill_config)    # build model and interacting
    slotfill(['I want cheap chinese food'])
    json.dump(slotfill_config, open('my_bot/slotfill_config.json', 'wt'))


def simple_bot():
    # train bot
    gobot_config = read_json(configs.go_bot.gobot_simple_dstc2)
    # templates
    # gobot_config['chainer']['pipe'][-1]['template_type'] = 'DefaultTemplate'
    gobot_config['chainer']['pipe'][-1]['template_path'] = 'my_data/simple-dstc2-templates.txt'
    # database
    gobot_config['chainer']['pipe'][-1]['database'] = {'class_name': 'sqlite_database',
                                                       'primary_keys': ["name"],
                                                       'save_path': 'my_bot/db.sqlite'}
    # slot filler
    gobot_config['chainer']['pipe'][-1]['slot_filler']['config_path'] = 'my_bot/slotfill_config.json'
    gobot_config['chainer']['pipe'][-1]['tracker']['slot_names'] = ['pricerange', 'this', 'area', 'food']
    # embedder (default)
    gobot_config['chainer']['pipe'][-1]['embedder'] = None

    gobot_config['metadata']['variables']['DATA_PATH'] = 'my_data'
    gobot_config['metadata']['variables']['MODEL_PATH'] = 'my_bot/model'

    gobot_config['train']['batch_size'] = 8  # set batch size
    gobot_config['train']['max_batches'] = 250  # maximum number of training batches
    gobot_config['train']['val_every_n_batches'] = 40  # evaluate on full 'valid' split each 30 batches
    gobot_config['train']['log_every_n_batches'] = 40  # evaluate on 20 batches of 'train' split every 30 batches
    gobot_config['train']['log_on_k_batches'] = 20

    train_model(gobot_config)
    evaluate_model(gobot_config)

    bot = build_model(gobot_config)
    print(bot(['cheap restaurant']))
    print(bot(['food']))


def best_bot():
    # train_model(configs.go_bot.gobot_dstc2_best)
    bot = build_model(configs.go_bot.gobot_dstc2_best, download=True)
    bot(['hi, i want chinese restaurant'])
    bot(['bye'])


if __name__ == '__main__':
    simple_bot()

    # best_bot()
